package com.appspot.codelab.docs.client.content.dialogs;

import com.appspot.codelab.docs.client.commands.SystemListDirectoryCommand;
import com.appspot.codelab.docs.client.events.CommandEvent;
import com.appspot.codelab.docs.client.repository.RepositoryDirectory;
import com.appspot.codelab.docs.client.widgets.DynamicDialog;
import com.appspot.codelab.docs.client.widgets.ExplorerTree;
import com.appspot.codelab.docs.client.widgets.ExplorerTree.ExpandHandler;
import com.appspot.codelab.docs.client.widgets.ExplorerTree.SelectionMode;
import com.appspot.codelab.docs.client.widgets.ExplorerTree.SelectionType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * A dialog window for listing files.
 */
public class DynamicFileListDialog extends DynamicDialog {

  /**
   * Contains File List Dialog contents.
   */
  protected class FileListDialogContents extends Composite {
	
	private Anchor refresh;
    private VerticalPanel panel;
    private ScrollPanel scroll;
    private ExplorerTree tree;
  
    /**
     * Constructs a new File List Dialog contents.
     */
	protected FileListDialogContents() {
      addClickHandler(new ClickHandler() {
          public void onClick(ClickEvent event) {
            hide();
          }
      });
      panel = new VerticalPanel();
      panel.setWidth("400px");
      panel.setVerticalAlignment(VerticalPanel.ALIGN_TOP);
      initWidget(panel);
      scroll = new ScrollPanel();
      tree = new ExplorerTree(projectName, null,
    	  SelectionType.NONE,
    	  SelectionMode.SINGLE,
    	  new ExpandHandler() {
		@Override
		public void getDirectory(String path,
		    final AsyncCallback<RepositoryDirectory> callback) {
		  CommandEvent.fire(
			  new SystemListDirectoryCommand(path, true,
			      new AsyncCallback<RepositoryDirectory>() {
					@Override
					public void onFailure(Throwable caught) {
					}
					@Override
					public void onSuccess(RepositoryDirectory result) {
					  callback.onSuccess(result);
					}
			  }));
		}
		@Override
		public String getUrl(String itemPath) {
	      if (GWT.isScript()) {
			return "?docpath=" + projectName + com.google.gwt.http.client.URL.encodeComponent(itemPath);
		  } else {
			return "?gwt.codesvr=3.1.4.20:9997&docpath=" + projectName + com.google.gwt.http.client.URL.encodeComponent(itemPath);
		  }
		}
	  });
	  tree.setSize("100%", "100%");
	  scroll.add(tree);
	  refresh = new Anchor("Refresh", "#");
	  refresh.addClickHandler(new ClickHandler(){
	    public void onClick(ClickEvent event) {
	      event.preventDefault();
	      event.stopPropagation();
	    }
	  });
	  panel.add(scroll);
	  onShowContent = new Runnable() {
		@Override
		public void run() {
		  resize();
		  if (tree.getItemCount() == 0) {
		    //loadEntries(true);
		  }
		} 
	  };
	}

	/**
	 * Resizes the dialog window to match the browser window size.
	 */
	private void resize() {
	  int targetHeight = Window.getClientHeight() - 180;
	  panel.setPixelSize(400, targetHeight);
	  scroll.setPixelSize(400, targetHeight - 40);
	  this.setWidth("400px");
	}
	
  }

  protected static DynamicFileListDialog instance;

  /**
   * Retrieves the single instance of this class.
   * 
   * @param selectionHandler the selection handler.
   */
  public static DynamicFileListDialog get(
	  String projectName) {
    if (instance == null) {
      instance = new DynamicFileListDialog();
    }
    instance.projectName = projectName;
    return instance;
  }
  
  protected String projectName;
  protected Runnable onShowContent;
  
  /**
   * Constructs a dialog window for selecting a file.
   */
  public DynamicFileListDialog() {
    super("Open File", true, "400px", null);
  }

  /**
   * Retrieves the dialog's contents asynchronously.
   * 
   * @param callback the callback carrying the content widget
   */
  @Override
  protected void getContents(final AsyncCallback<Widget> callback) {
    GWT.runAsync(new RunAsyncCallback() {
		@Override
		public void onFailure(Throwable reason) {
		}
		@Override
		public void onSuccess() {
	      callback.onSuccess(new FileListDialogContents());
	      center();
		}
    });
  }

  /**
   * Makes the dialog window visible.
   */
  @Override
  public void show() {
    super.show();
    if (onShowContent != null) {
      onShowContent.run();
    }
  }
  
}
